/**
 * 
 */
package main.org.action;

import java.math.BigDecimal;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.compiere.model.I_BPM_PaymentMonth;
import org.compiere.model.I_C_UOM;
import org.compiere.model.MBPMPaymentMonth;
import org.compiere.model.Query;
import org.compiere.util.CLogger;
import org.compiere.util.DB;
import org.compiere.util.Env;
import main.org.model.Budget;
import main.org.model.Period;
import main.org.model.Utils;

/**
 * @author V.Sokolov
 * 
 */
public class PeriodAmount extends Budget implements ServletRequestAware,
		ServletResponseAware {

	/**
	 * 
	 */
	private static final long serialVersionUID = 8588479221768360808L;
	/** Logger */
	protected CLogger log = CLogger.getCLogger(getClass());

	private String name;
	private Period[] period;
	private Period[] periodBean;
	private int sQuantity;
	private String sAmount;
	private final String sessionKey = "periodamount";
	private HttpServletRequest request;
	private HttpServletResponse response;
	LinkedHashMap<Integer, String> uomList = new LinkedHashMap<Integer, String>();
	LinkedHashMap<Integer, String> paymentList = new LinkedHashMap<Integer, String>();

	/* 
	 */
	@Override
	public String execute() throws Exception {

		setPeriod(getValues(callID, tableID, recordID));
		setPage(Utils.TEMPLATE_THREE);
		getClass().getDeclaredFields();
		setUomList();
		setPaymentList();
		session.put(sessionKey, this);

		return SUCCESS;
	}

	public String getName() {
		return name;
	}

	public LinkedHashMap<Integer, String> getPaymentList() {
		return paymentList;
	}

	public Period[] getPeriod() {
		return period;
	}

	public Period[] getPeriodBean() {
		return periodBean;
	}

	public String getsAmount() {
		return sAmount;
	}

	public HttpServletResponse getServletResponse() {
		return response;
	}

	public int getsQuantity() {
		return sQuantity;
	}

	public LinkedHashMap<Integer, String> getUomList() {
		return uomList;
	}

	public Period[] getValues(int callID, int tableID, int recordID) {

		Period values = null;
		List<Period> list = new ArrayList<Period>();
		PreparedStatement pstmt = null;
		ResultSet rs = null;

		String sql = "select bv.name, u.name as uom, u.c_uom_id as uomID, "
				+ "			 p.c_period_id as periodID, p.c_year_id as yearID, "
				+ "			 p.name as mth, t.quantity, round(t.amountUnit,2) as amountUnit, "
				+ "			 round(t.amount,2) as amount, t.bpm_paymentMonth_ID as payMonth, pm.name as paymentMonthName, bv.description \n"
				+ "from bpm_budgetcallLine t \n"
				+ "join c_uom_trl u on u.c_uom_id=t.c_uom_id \n"
				+ "join c_period p on p.c_period_id=t.c_period_id \n"
				+ "join bpm_budget_v bv on bv.bpm_budgetCall_id=t.bpm_budgetCall_id and bv.ad_table_id=t.ad_table_id and bv.record_id=t.record_id \n"
				+ "join bpm_paymentMonth pm on pm.bpm_paymentMonth_id=t.bpm_paymentMonth_id \n"
				+ "where t.bpm_budgetCall_id=? and t.ad_table_id=? and t.record_id=? \n"
				+ "order by t.C_period_id";

		try {
			pstmt = DB.prepareStatement(sql, null);
			pstmt.setInt(1, callID);
			pstmt.setInt(2, tableID);
			pstmt.setInt(3, recordID);
			rs = pstmt.executeQuery();

			int sQuantity = 0;
			BigDecimal sAmount = new BigDecimal(0);
			while (rs.next()) {
				values = new Period();
				values.setName(rs.getString("name"));
				values.setUom(rs.getString("uom"));
				values.setUomID(rs.getInt("uomid"));
				values.setPeriodID(rs.getInt("periodid"));
				values.setYearID(rs.getInt("yearid"));
				values.setMonth(rs.getString("mth"));
				values.setPayMonth(rs.getInt("payMonth"));
				values.setPayMonthName(rs.getString("paymentmonthname"));
				values.setQuantity(rs.getString("quantity"));
				values.setAmountUnit(rs.getString("amountunit"));
				values.setAmount(String.valueOf(rs.getBigDecimal("amount")));
				values.setDescription(rs.getString("description"));
				sQuantity = sQuantity
						+ Integer.parseInt(rs.getString("quantity"));
				sAmount = sAmount.add(rs.getBigDecimal("amount"));
				list.add(values);
			}

			setsQuantity(sQuantity);
			setsAmount(String.valueOf(sAmount));

		} catch (SQLException e) {
			log.log(Level.INFO, "product", e);
		} finally {
			DB.close(rs, pstmt);
			rs = null;
			pstmt = null;
		}

		return list.toArray(new Period[list.size()]);
	}

	/*
	 */
	@Override
	public String input() throws Exception {

		int count = Integer.valueOf(request.getParameter("rowspan"));
		String upd = "update bpm_budgetCallLine ";
		String set = "";
		String where = " where bpm_budgetCall_id=" + callID
				+ "\n and c_charge_ID=" + chargeID + "\n and ad_table_ID="
				+ tableID + "\n and record_ID=" + recordID;
		String periodSql = "";

		int idx = 1;
		int quentity = 0;
		double amountUnit = 0.;
		double amount = 0.;
		int uomID = 0;
		int paymentID = 0;
		for (int i = 0; i < count; i++) {

			quentity = Integer.valueOf(request.getParameter("quantity_IDX_"
					+ idx));
			amountUnit = Double.valueOf(request.getParameter("amountUnit_IDX_"
					+ idx));
			amount = Double.valueOf(request.getParameter("amount_IDX_" + idx));
			uomID = Integer.parseInt(request.getParameter("uom_IDX_" + idx));
			paymentID = Integer.parseInt(request.getParameter("payment_IDX_"
					+ idx));

			periodSql = "\n and c_period_ID="
					+ Integer
							.valueOf(request.getParameter("period_IDX_" + idx));
			set = " set quantity=" + quentity;
			set += "\n ,amountUnit=" + amountUnit;
			set += "\n ,amount=" + amount;
			set += "\n ,c_uom_id=" + uomID;
			set += "\n ,bpm_paymentMonth_id=" + paymentID;

			DB.executeUpdate(upd + set + where + periodSql, null);
			periodSql = "";
			idx++;
		}

		setsQuantity(Integer.valueOf(request.getParameter("sQuantity")));
		setsAmount(request.getParameter("sAmount"));

		PeriodAmount pa = (PeriodAmount) session.get(sessionKey);
		pa.setsQuantity(Integer.valueOf(request.getParameter("sQuantity")));
		pa.setsAmount(request.getParameter("sAmount"));
		session.put(sessionKey, pa);

		return INPUT;
	}

	/**
	 * Load All Periods from Year
	 * 
	 * @param yearID
	 */
	private void loadPayments(Properties ctx) {

		List<MBPMPaymentMonth> list = new Query(ctx,
				I_BPM_PaymentMonth.Table_Name, "IsActive='Y'", null)
				.setOrderBy(I_BPM_PaymentMonth.COLUMNNAME_LineNo).list();

		for (MBPMPaymentMonth p : list) {
			this.paymentList.put(p.get_ID(), p.getName());
		}
	} // loadPeriods

	/**
	 * Load All UOMs
	 * 
	 * @param ctx
	 *            context
	 */
	private void loadUOMs(Properties ctx) {
		PreparedStatement pstmt = null;
		ResultSet rs = null;

		String sql = "select c_uom_id, name from " + I_C_UOM.Table_Name
				+ "_trl where isActive='Y' order by name";

		try {
			pstmt = DB.prepareStatement(sql, null);
			rs = pstmt.executeQuery();
			while (rs.next()) {
				this.uomList.put(rs.getInt("c_uom_id"), rs.getString("name"));
			}

		} catch (SQLException e) {
			log.log(Level.INFO, "product", e);
		} finally {
			DB.close(rs, pstmt);
			rs = null;
			pstmt = null;
		}
	} // loadUOMs

	public HttpServletRequest request() {
		return request;
	}

	public void setName(String name) {
		this.name = name;
	}

	public void setPaymentList() {
		loadPayments(Env.getCtx());
	}

	public void setPeriod(Period[] period) {
		this.period = period;
	}

	public void setPeriodBean(Period[] periodBean) {
		if (periodBean == null)
			this.periodBean = getValues(callID, tableID, recordID);
		else
			this.periodBean = periodBean;
	}

	public void setsAmount(String sAmount) {
		this.sAmount = sAmount;
	}

	public void setServletRequest(HttpServletRequest request) {
		this.request = request;
	}

	public void setServletResponse(HttpServletResponse response) {
		this.response = response;
	}

	public void setsQuantity(int sQuantity) {
		this.sQuantity = sQuantity;
	}

	public void setUomList() {
		loadUOMs(Env.getCtx());
	}

}
